package com.example.drive.db

sealed class CompareCondition(val condition: String, val value: Any) {
    /**
     * 查询列名field值是value的数据
     */
    class Equal(field: String, value: Any) : CompareCondition("where $field = ?", value)

    /**
     * 查询列名field值不是value的数据
     */
    class NotEqual(field: String, value: Any) : CompareCondition("where $field != ?", value)

    /**
     * 查询列名field值大于value的数据
     */
    class Greater(field: String, value: Any) : CompareCondition("where $field > ?", value)

    /**
     * 查询列名field值大于等于value的数据
     */
    class GreaterOrEqual(field: String, value: Any) : CompareCondition("where $field >= ?", value)

    /**
     * 查询列名field值小于value的数据
     */
    class Less(field: String, value: Any) : CompareCondition("where $field < ?", value)

    /**
     * 查询列名field值小于等于value的数据
     */
    class LessOrEqual(field: String, value: Any) : CompareCondition("where $field <= ?", value)
}

sealed class InCondition(val condition: String) {
    class IN(field: String, target: Set<Any>) : InCondition(
        "where $field IN ${target.toArgs()}"
    )

    class NotIn(field: String, target: Set<Any>) : InCondition(
        "where $field NOT IN ${target.toArgs()}"
    )
}

/**
 * 拼接参数
 *
 * [prefix] 前缀
 * [suffix] 后缀
 */
fun <T> Iterable<T>.toArgs(prefix: String = "(", suffix: String = ")"): String {
    val builder = StringBuilder(prefix)
    forEach {
        if (it is String) {
            // 字符串需要拼接一个单引号
            builder.append("'$it',")
        } else {
            builder.append("$it,")
        }
    }
    return builder.substring(0, builder.length - 1).plus(suffix)
}

abstract class BaseCondition(val condition: String)

/**
 * 模糊匹配
 */
sealed class FuzzyCondition(condition: String) : BaseCondition(condition) {
    class Like constructor(field: String, target: Any) : FuzzyCondition(
        "where $field LIKE '%$target%'"
    )

    class NotLike constructor(field: String, target: Any) : FuzzyCondition(
        "where $field NOT LIKE '%$target%'"
    )
}

/**
 * 排序
 */
sealed class OrderCondition(condition: String) : BaseCondition(condition) {
    class ASC constructor(fieldOrderBy: String) : OrderCondition(
        "order by $fieldOrderBy ASC"
    )

    class DESC constructor(fieldOrderBy: String) : OrderCondition(
        "order by $fieldOrderBy DESC"
    )
}